package com.scalar.chiptrack.operations.proformainvoice.actions;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.MessageResources;

import com.scalar.ScalarException;
import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.commons.Address;
import com.scalar.chiptrack.commons.Labels;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.operations.packingslip.PackingSlipComparator;
import com.scalar.chiptrack.operations.proformainvoice.BankInfo;
import com.scalar.chiptrack.operations.proformainvoice.dao.ProFormaInvoiceDAO;
import com.scalar.chiptrack.sales.LineItem;
import com.scalar.chiptrack.sales.SalesOrder;
import com.scalar.chiptrack.sales.SubTotal;
import com.scalar.chiptrack.sales.actions.SalesOrderAction;
import com.scalar.chiptrack.sales.dao.SalesDAO;
import com.scalar.chiptrack.sales.dao.SalesOrderDAO;
import com.scalar.chiptrack.sales.forms.ApproverOrderForm;
import com.scalar.chiptrack.users.Functionality;
import com.scalar.chiptrack.users.User;
import com.scalar.chiptrack.utils.ConfigManager;
import com.scalar.chiptrack.utils.PDFGenerator;
import com.scalar.chiptrack.utils.StringUtils;

/**
 * Implementation of <strong>Action</strong> that gives customers list,
 * search with customer name, create sales order
 *
 * @author
 * @version
 */

public final class ProFormaAction extends ChipTrackAction
{

    // ----------------------------------------------------- Instance Variables

    private static final String ACTION_NAME = "/order.do";
    public ApproverOrderForm subform;

    // --------------------------------------------------------- Public Methods

    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     *
     * @param mapping The ActionMapping used to select this instance
     * @param form The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception Exception if business logic throws an exception
     */
    public ActionForward execute ( ActionMapping mapping,
                                   ActionForm form,
                                   HttpServletRequest request,
                                   HttpServletResponse response )
            throws Exception
    {

        // Extract attributes and parameters we will need
        subform = ( ApproverOrderForm ) form;
        String action = request.getParameter ( "action" );

        HttpSession session = request.getSession ();
        User users = ( User ) session.getAttribute ( SessionKeys.USER_KEY );

        if ( users == null )
        {
            session.setAttribute ( SessionKeys.SOURCE_PAGE_KEY, ACTION_NAME + "?" + request.getQueryString () );
            return ( mapping.findForward ( "login" ) );
        }

        LineItem lineitem = new LineItem ();

        // Validate the request parameters specified by the user
        ActionErrors errors = new ActionErrors ();

        String salesOrderId = "";
        try
        {
            salesOrderId = request.getParameter ( "salesOrderId" );
        }
        catch ( NullPointerException e )
        {
            salesOrderId = "";
        }
        String salesOrderNo = request.getParameter ( "salesOrderNo" );
        if ( ( salesOrderId != null ) || ( salesOrderNo != null ) )
        {
            if ( subform == null )
                subform = new ApproverOrderForm ();

            String isSales = request.getParameter ( "isSales" );
            SalesOrder salesOrder = null;


            /*
             To faciliate the end user to understand that he cannot make any modifications
             in that screen
             */
            if ( users.isActionAllowed ( Functionality.SALES_VIEW_ORDER,
                                         User.USER_ACTION_MODIFY ) )
            {
                request.setAttribute ( "showMessage", "FALSE" );

            }
            else
            {
                request.setAttribute ( "showMessage", "TRUE" );
            }

            if ( salesOrderId != null )
            {
                if ( ( isSales != null ) && ( isSales.equals ( "FALSE" ) ) )
                {
                    salesOrder = SalesOrderDAO.loadOnlineOrder ( salesOrderId );
                }
                else
                {
                    salesOrder = SalesOrderDAO.loadSalesOrder ( salesOrderId );

                }
            }
            else if ( salesOrderNo != null )
            {
                salesOrder = SalesOrderDAO.loadSalesOrderBySalesOrderNo ( salesOrderNo );
            }

            // Commented by veeru on 16th June 2004
            /*
            if ( (! salesOrder.getEndUser ().trim ().equals ( "" ) ) )
            {
                int endUserId = EndUserDAO.getEndUserIdByName ( salesOrder.getEndUser (), salesOrder.getCustomerId () );

                ApproveOrderAction.loadEndUserContactPersonDetails ( salesOrder, endUserId );
            }*/

            //Get the Holds for this orderId
            HashMap holds = SalesDAO.loadHoldsForOrder ( salesOrder.getSalesOrderId () );

            Iterator holdBy = holds.keySet ().iterator ();
            Iterator user = holds.values ().iterator ();

            //Loop thru the hold list and set the holds in the form
            while ( holdBy.hasNext () )
            {
                String holdedBy = ( String ) holdBy.next ();

                if ( holdedBy.equalsIgnoreCase ( "Finance" ) )
                {
                    subform.setFinanceHold ( true );
                    subform.setFinanceHoldUser ( ( String ) user.next () );
                }
                else if ( holdedBy.equalsIgnoreCase ( "Operations" ) )
                {
                    subform.setOperationsHold ( true );
                    subform.setOperationsHoldUser ( ( String ) user.next () );
                }
                else if ( holdedBy.equalsIgnoreCase ( "Sales" ) )
                {
                    subform.setSalesHold ( true );
                    subform.setSalesHoldUser ( ( String ) user.next () );
                }
                else if ( holdedBy.equalsIgnoreCase ( "Marketing" ) )
                {
                    subform.setMarketingHold ( true );
                    subform.setMarketingHoldUser ( ( String ) user.next () );
                }
            }

            //Load the reason codes in request

            request.setAttribute ( "marketingReasonCodes", SalesDAO.loadMarketingReasonCodes () );
            request.setAttribute ( "salesReasonCodes", SalesDAO.loadSalesReasonCodes () );
            request.setAttribute ( "financeReasonCodes", SalesDAO.loadFinanceReasonCodes () );
            request.setAttribute ( "opsReasonCodes", SalesDAO.loadOpsReasonCodes () );

            //Set the salesOrder into FormBean
            subform.setSalesOrderId ( salesOrder.getSalesOrderId () );
            subform.setSalesOrderNo ( salesOrder.getSalesOrderNo () );

            int customerId = SalesOrderDAO.loadCustomerId ( salesOrder.getSalesOrderId () );

            //Set the current order lineItems
            if ( ( isSales != null ) && ( isSales.equals ( "FALSE" ) ) )
            {
                request.setAttribute ( "lineItems",
                                       SalesOrderDAO.loadOnlineOrderLineItems ( salesOrder.getSalesOrderId () ) );
            }
            else
            {
                //To get customer part numbers
                ArrayList cancelledList = SalesOrderDAO.loadCancelledOrderLineItemsByCustomerId ( salesOrder.getSalesOrderId (), customerId );
                if ( cancelledList.size () == 0 )
                    request.setAttribute ( "cancelledShow", "FALSE" );
                else
                    request.setAttribute ( "cancelledShow", "TRUE" );

                ArrayList changedList = SalesOrderDAO.loadOnlyChangeOrderLineItems ( salesOrder.getSalesOrderId () );
                if ( changedList.size () == 0 )
                    request.setAttribute ( "changedShow", "FALSE" );
                else
                    request.setAttribute ( "changedShow", "TRUE" );

                //To get customer part numbers
                  ArrayList presentList = SalesOrderDAO.loadOrderLineItemsByCustomerId ( salesOrder.getSalesOrderId (), customerId );


                /*if ( !( salesOrder.getEndUser ().trim ().equals ( "" ) ) )
                {
                    int endUserId = EndUserDAO.getEndUserIdByName ( salesOrder.getEndUser (), salesOrder.getCustomerId () );
                    SalesOrderDAO.loadEndUserPartNumbersForLineItems ( null, presentList, endUserId );
                    SalesOrderDAO.loadEndUserPartNumbersForLineItems ( null, changedList, endUserId );
                    SalesOrderDAO.loadEndUserPartNumbersForLineItems ( null, cancelledList, endUserId );
                }*/
                //SalesOrderDAO.loadCustomerPartNumbersForLineItems( null, presentList, salesOrder.getCustomerId(), salesOrder.getOdmId() );
                //SalesOrderDAO.loadCustomerPartNumbersForLineItems( null, changedList, salesOrder.getCustomerId(), salesOrder.getOdmId() );
                //SalesOrderDAO.loadCustomerPartNumbersForLineItems( null, cancelledList, salesOrder.getCustomerId(), salesOrder.getOdmId() );

                String lastStatus[] = new String[presentList.size ()];
                int totalQty = 0;
                double totalAmt = 0.0;
				double salesTax = 0.0;
                for ( int i = 0; i < presentList.size (); i++ )
                {

                    LineItem templineItem = ( LineItem ) presentList.get ( i );
                    coolstatus = templineItem.getStatus ();
                    lastStatus[i] = coolstatus;
                    totalQty = totalQty + templineItem.getQuantity ();
                    totalAmt = totalAmt + templineItem.getAmountAsDouble ();
                    float taxvalue = SalesOrderDAO.getTaxValue ( null, salesOrder.getSalesTaxType () );

                    if ( templineItem.getIsTaxable () )
                    {
						Float ff = new Float(taxvalue);
						double tax = ff.doubleValue();

						salesTax = salesTax + ( templineItem.getAmountAsDouble () * ( tax / 100 ) );
                    }
                }

				salesOrder.setSalesTaxAsDouble(salesTax );
				salesOrder.setSubTotalAsDouble(totalAmt);
				salesOrder.setOrderTotalAsDouble(salesOrder.getSubTotalAsDouble()+salesOrder.getFrieghtAsDouble()+salesOrder.getMiscAsDouble()+salesOrder.getSalesTaxAsDouble());


				salesOrder.setChangeNumber ( SalesOrderDAO.loadChangeNo ( salesOrder.getSalesOrderId () ) - 1 );

                subform.setSalesOrder ( salesOrder );
                request.setAttribute ( "approverOrderForm", subform );

                request.setAttribute ( "lineitemstatus", lastStatus );

                if ( presentList.size () == 0 )
                    request.setAttribute ( "presentShow", "FALSE" );
                else
                    request.setAttribute ( "presentShow", "TRUE" );

                request.setAttribute ( "lineItems", presentList );
                request.setAttribute ( "lineItemsWithSubtotals", SalesOrderAction.loadLineItemsWithSubTotals ( ( ArrayList ) request.getAttribute ( "lineItems" ) ) );

                request.setAttribute ( "changeLineItems", changedList );
                request.setAttribute ( "cancelledLineItems", cancelledList );
            }

            //Put the lineItem holds in the request..
            request.setAttribute ( SessionKeys.INFO_MESSAGES, SalesDAO.loadLineItemHolds ( salesOrder.getSalesOrderId () ) );
            request.setAttribute ( SessionKeys.ERROR_MESSAGES, SalesDAO.loadHoldCancelledLineItems ( salesOrder.getSalesOrderId () ) );
            request.setAttribute ( "termsAndConditions", SalesDAO.loadTermsAndConditionsAsList () );

            //return to the approver page, where approver can approve/reject

            if ( "printOrder".equalsIgnoreCase ( action ) )
            {

                //For sorting the line items based on PO Line Item Number
                if ( request.getAttribute ( "lineItems" ) != null )
                    Collections.sort ( ( ArrayList ) request.getAttribute ( "lineItems" ), new PackingSlipComparator () );


                request.setAttribute ( "lineItemsWithSubtotals", loadLineItemsWithSubTotals ( ( ArrayList ) request.getAttribute ( "lineItems" ) ) );

                if ( request.getAttribute ( "changeLineItems" ) != null )
                    Collections.sort ( ( ArrayList ) request.getAttribute ( "changeLineItems" ), new PackingSlipComparator () );
                if ( request.getAttribute ( "cancelledLineItems" ) != null )
                    Collections.sort ( ( ArrayList ) request.getAttribute ( "cancelledLineItems" ), new PackingSlipComparator () );

                return ( mapping.findForward ( "printOrder" ) );
            }

            if ( "customerOrder".equalsIgnoreCase ( action ) )
            {
                return ( mapping.findForward ( "customerOrder" ) );
            }

            if ( "cancelledOrder".equalsIgnoreCase ( action ) )
            {
                return ( mapping.findForward ( "cancelledOrder" ) );
            }

            if ( "salesOrderView".equalsIgnoreCase ( action ) )
            {
                return ( mapping.findForward ( "salesOrderView" ) );
            }


            if ( "salesOrderViewMain".equalsIgnoreCase ( action ) )
            {
                return ( mapping.findForward ( "salesOrderViewMain" ) );
            }
            return ( mapping.findForward ( "viewOrder" ) );
        }

        return ( mapping.findForward ( "success" ) );
    }

    //Added by gandhi on 28 May 2004 to send ProFormaInvoice through Email
    public static String getProFormaHtmlFile ( String host, String salesOrderId ) throws ScalarException
    {
        String filePath = null;
        SalesOrder salesOrder = null;
        BankInfo bankInfo = null;
        if ( salesOrderId != null )
        {
            salesOrder = SalesOrderDAO.loadSalesOrder ( salesOrderId );
            bankInfo = ProFormaInvoiceDAO.loadBankInfo(Integer.parseInt(salesOrderId));
        }
        //To get customer part numbers

        int customerId = SalesOrderDAO.loadCustomerId ( salesOrder.getSalesOrderId () );

        // System.out.println("customerId  "+  customerId);
        ArrayList presentList = SalesOrderDAO.loadOrderLineItemsByCustomerId ( salesOrder.getSalesOrderId (), customerId );
        int odmId = salesOrder.getOdmId() ;
        //SalesOrderDAO.loadCustomerPartNumbersForLineItems ( null, presentList, customerId, odmId );


        if ( presentList != null )
        {
            Collections.sort ( presentList, new PackingSlipComparator () );
        }


        /*if ( ! ( salesOrder.getEndUser ().trim ().equals ( "" ) ) )
        {
            int endUserId = EndUserDAO.getEndUserIdByName ( salesOrder.getEndUser (), salesOrder.getCustomerId () );
            // Commented by veeru on 16th June 2004
            //ApproveOrderAction.loadEndUserContactPersonDetails ( salesOrder, endUserId );

            SalesOrderDAO.loadEndUserPartNumbersForLineItems ( null, presentList, endUserId );

        }*/

        String psAsHtml = formatAsHTML ( host, salesOrder, presentList, bankInfo );

        if ( psAsHtml == null )
        {
            return filePath;
        }

        FileWriter fWriter = null;
        File psAttachment = null;

        try
        {
            // CREATE TEMPORARY ATTACHMENT FILE
            File tempDir = new File ( "chiptrac_temp_dir" ).getCanonicalFile ();
            tempDir.mkdir ();

            String proformaAttachmentFileName = null;
            String salesNo = salesOrder.getSalesOrderNo ();

            proformaAttachmentFileName = "Pro_Forma_Invoice#  " + salesNo + ".html";
            psAttachment = new File ( tempDir.getCanonicalPath (), proformaAttachmentFileName );
            psAttachment.deleteOnExit ();

            if ( ( psAttachment.exists () == true ) || ( psAttachment.createNewFile () == true ) )
            {
                fWriter = new FileWriter ( psAttachment, false );

                fWriter.write ( psAsHtml );

                fWriter.close ();
                fWriter = null;

                filePath = psAttachment.getAbsolutePath ();
            }
        }
        catch ( Exception e )
        {
            System.out.println ( "Exception while creating Pro Forma Invoice html file" );
            e.printStackTrace ();
        }
        finally
        {
            if ( fWriter != null )
            {
                try
                {
                    fWriter.close ();
                    fWriter = null;
                }
                catch ( IOException ignore )
                {
                }
            }
        }

        return filePath;
    }


    //Added by gandhi on 28 May 2004 to send ProFormaInvoice through Email
    public static String formatAsHTML ( String host, SalesOrder salesOrder, ArrayList presentList, BankInfo bankInfo ) throws ScalarException
    {
        StringBuffer buf = new StringBuffer ( 2098 );


        buf.append ( "<HTML><HEAD><TITLE>Scalarsoft - ChipTrac</TITLE>" );
        buf.append ( "<LINK href='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/stylesheets/scalarsoft.css' type=text/css rel=stylesheet>" );
        buf.append ( "<style type='text/css'>" );
        buf.append ( "a { text-decoration : none}" );
        buf.append ( "</style>" );

        buf.append ( "</HEAD><BODY bgColor='#ffffff' leftMargin=0 topMargin=0 marginheight='0' marginwidth='0'>" );
        buf.append ( "<center><h2>Pro Forma Invoice</h2></center>" );
        buf.append ( "<!-- from here your body starts -->" );

        buf.append ( "<Div1><table width='95%' cellspacing='0' cellpadding='0' border='0' align=center>" );

        buf.append ( " <tr>" );
        buf.append ( "<td width='34%' align='center'><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/scalar_logo.jpg' height='72' width='180' border=0></td>" );
        buf.append ( "<td width='1%'><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif'></td>" );
        Address clientAddress = salesOrder.getClientAddressAsObject ();
        // To display Client address
        buf.append ( "<td width='30%' align='center' class='NArialL'><br>" + salesOrder.getClientName () );
        buf.append ( "<br>" );
        buf.append ( salesOrder.getClientAddressAsHTML () );
        buf.append ( " </tr>" );

        buf.append ( "<tr><td width='1%'><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif'></td></tr>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );

        String customerName = salesOrder.getCustomerName ();
        if ( salesOrder.getCustomerName ().equals ( salesOrder.getContactPerson () ) )
        {
            customerName = null;
        }

        buf.append ( " <tr>" );
        buf.append ( "<td height='100%'>" );//To set All three OrderedBy,BillTo and ShipTo address table same height
        buf.append ( "<table height='100%' border=1 width='100%' bordercolor='#000000' cellspacing='0' cellpadding='0'>" );
        buf.append ( "<tr height=20><td class='NArialL' bgcolor='#DEE1E2'>Bill To :</td></tr>" );
        buf.append ( "<tr height=20><td valign='top' class='NArialL' bgcolor='#FFFFEE'>" );
        buf.append ( "<table width='100%' class='NArialL' height=80 cellspacing='0' cellpadding='0'>" );
        buf.append ( "<tr><td valign='top'>" );


        if( salesOrder.getBillingAddressAsObject().getContactPerson() != null && salesOrder.getCustomerName().trim().length() !=0 )
        {
            if( ! salesOrder.getBillingAddressAsObject().getContactPerson().equals( salesOrder.getCustomerName() ) )
            {
                 buf.append(customerName + "<br>");
            }
        }

        buf.append (  salesOrder.getBillingAddressAsHTML() + "</td></tr>" );
        buf.append ( "</table>" );
        buf.append ( "</tr>" );
        buf.append ( "</table>" );
        buf.append ( "</td>" );

        buf.append ( "<td width='1%'><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif'></td>" );

        buf.append ( "<td height='100%'>" );
        buf.append ( "</td>" );

        buf.append ( "<td width='1%'><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif'></td>" );

        buf.append ( "<td height='100%'>" ); //To set All three BillTo and ShipTo address table same height
        buf.append ( "<table height='100%' border=1 width='100%' bordercolor='#000000' cellspacing='0' cellpadding='0'>" );
        buf.append ( "<tr height=20><td class='NArialL' bgcolor='#DEE1E2'>Ship To :</td></tr>" );
        buf.append ( "<tr height=20><td valign='top' class='NArialL' bgcolor='#FFFFEE'>" );
        buf.append ( "<table width='100%' class='NArialL' height=80 cellspacing='0' cellpadding='0'>" );

        //buf.append ( "<tr><td valign='top'>" + salesOrder.getCustomerName () + "<br>" );
        buf.append ( "<tr><td valign='top'>" + ( salesOrder.getOdm() != null && salesOrder.getOdm().length() > 0 ? salesOrder.getOdm () : salesOrder.getCustomerName () ) +"<br>" );

		buf.append (  salesOrder.getShippingAddressAsHTML() + "</td></tr>" );
        buf.append ( "</table>" );
        buf.append ( "</tr>" );
        buf.append ( "</table>" );
        buf.append ( "</td>" );

        buf.append ( "</tr>" );

        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif'></td></tr>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif'></td></tr>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );

        buf.append ( "<tr>" );
        buf.append ( "<td class='NArialL' height='20'>" );
        buf.append ( "<table width='100%' class='NArialL' border=1 bordercolor='#000000' cellspacing='0' cellpadding='0'>" );
        buf.append ( "<tr height=20><td bgcolor='#DEE1E2'> Customer PO#</td><td bgcolor='#DEE1E2'>Sales Order#</td></tr>" );
        buf.append ( "<tr height=20><td bgcolor='#FFFFEE'>" + salesOrder.getCustomerPO () + "&nbsp;</td><td bgcolor='#FFFFEE'>" + salesOrder.getSalesOrderNo () + " &nbsp;</td></tr>" );
        buf.append ( "</table>" );
        buf.append ( "</td>" );
        buf.append ( "<td width='1%'><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif'></td>" );
        buf.append ( "<td class='NArialL' height='20'>" );
        buf.append ( "<table width='100%' class='NArialL' border=1 bordercolor='#000000' cellspacing='0' cellpadding='0'>" );
        buf.append ( "<tr height=20><td bgcolor='#DEE1E2'> Order Date</td><td bgcolor='#DEE1E2'>Ship Via</td></tr>" );
        buf.append ( "<tr height=20><td bgcolor='#FFFFEE'>" + ( (salesOrder.getBookingdateAsString () == null || salesOrder.getBookingdateAsString ().equals("null")) ? "" : salesOrder.getBookingdateAsString ()) + "&nbsp;</td><td bgcolor='#FFFFEE'>" + ( (salesOrder.getShippingMethod () == null || salesOrder.getShippingMethod ().equals("")) ? "" : salesOrder.getShippingMethod ()) + "&nbsp;</td></tr>" );
        buf.append ( "</table>" );
        buf.append ( "</td>" );
        buf.append ( "<td width='1%'><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif'></td>" );
        buf.append ( "<td class='NArialL' height='20'>" );
        buf.append ( "<table width='100%' class='NArialL' border=1 bordercolor='#000000' cellspacing='0' cellpadding='0'>" );
        buf.append ( "<tr height=20><td  bgcolor='#DEE1E2'>Sales Person</td><td bgcolor='#DEE1E2'>Regional Rep</td><td bgcolor='#DEE1E2'>Del Terms</td><td bgcolor='#DEE1E2'>Pay Terms</td></tr>" );
        buf.append ( "<tr height=20><td bgcolor='#FFFFEE'>" + salesOrder.getSalesPerson () + "&nbsp;</td><td bgcolor='#FFFFEE'>" + salesOrder.getRegionalRep () + "&nbsp;</td><td bgcolor='#FFFFEE'>" + salesOrder.getDeliveryTerms () + "&nbsp;</td><td bgcolor='#FFFFEE'>" + ( salesOrder.getShippingTerms ().trim ().equals ( "-1" ) ? "" : salesOrder.getShippingTerms () ) + "&nbsp;</td></tR>" );
        buf.append ( "</table>" );
        buf.append ( "</td>" );
        buf.append ( "</tr>" );

        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );

        buf.append ( "<tr><td colspan='5'>" );
        buf.append ( "<table width='100%' border=1 bordercolor='#000000' cellspacing='0' cellpadding='0'>" );
        buf.append ( "<tr height=20>" );
        buf.append ( "<td bgcolor='#DEE1E2' class='NArialL' align=center>PO Line#</td>" );
        buf.append ( "<td bgcolor='#DEE1E2' class='NArialL' align=center>Ship Qty</td>" );
        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>UM</td>" );

        String mfgPartNumberLabel = MessageResources.getMessageResources ( Labels.APPLICATION_RESOURCE_PROPERTIES ).getMessage ( "label.mfgPartNumber" );
        if ( mfgPartNumberLabel == null )
        {
            mfgPartNumberLabel = Labels.DEFAULT_MFG_PART_NUMBER_LABEL;
        }

        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>" + mfgPartNumberLabel + "</td>" );


        String customerPartNumberLabel = MessageResources.getMessageResources ( Labels.APPLICATION_RESOURCE_PROPERTIES ).getMessage ( "label.customerPartNumber" );
        if ( customerPartNumberLabel == null )
        {
            customerPartNumberLabel = Labels.DEFAULT_CUSTOMER_PART_NUMBER_LABEL;
        }

        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>" + customerPartNumberLabel + "</td>" );
        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>Product Description</td>" );
        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>Requested<br>Dock Date</td>" );
        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>Scheduled<br>Ship Date</td>" );
        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>Revised<br>Ship Date</td>" );
        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>Taxable</td>" );
        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>Unit<br>Price</td>" );
        buf.append ( "<td class='NArialL' bgcolor='#DEE1E2' align=center>Extended<br>Price</td>" );

        buf.append ( "</tr>" );

        LineItem lineItem = null;

        ArrayList presentListWithSubtotals = loadLineItemsWithSubTotals ( presentList );

        for ( int i = 0; i < presentListWithSubtotals.size (); i++ )
        {
            HashMap hashMap = ( HashMap ) presentListWithSubtotals.get ( i );
            Iterator iterator = hashMap.keySet ().iterator ();
            while ( iterator.hasNext () )
            {
                ArrayList list = ( ArrayList ) iterator.next ();
                SubTotal subTotal = ( SubTotal ) hashMap.get ( list );
                String subTotalQty = subTotal.getSubTotalQty ();
                String subTotalAmt = subTotal.getSubTotalAmt ();

                int size = list.size ();
                for ( int j = 0; j < size; j++ )
                {
                    lineItem = ( LineItem ) list.get ( j );
                    buf.append ( "<tr height=20>" );
                    buf.append ( "<td bgcolor='#FFFFEE'  class='NArialL' align=center>" + lineItem.getPoLineItemNo () + "&nbsp;</td>" );
                    buf.append ( "<td bgcolor='#FFFFEE'  class='NArialL' align=center>" + lineItem.getQtyAsString() + "&nbsp;</td>" );
                    buf.append ( "<td  class='NArialL' bgcolor='#FFFFEE' align=center>ea</td>" );
                    buf.append ( "<td bgcolor='#FFFFEE'  class='NArialL' align=center nowrap>" + lineItem.getManufacturingPartNo () + "&nbsp;</td>" );
                    buf.append ( "<td bgcolor='#FFFFEE'  class='NArialL' align=center nowrap>" + lineItem.getCustomerPartNo () + "&nbsp;</td>" );
                    buf.append ( "<td bgcolor='#FFFFEE'  class='NArialL' wrap>" + lineItem.getLineItemDescription () + "&nbsp;</td>" );
                    buf.append ( "<td  class='NArialL' bgcolor='#FFFFEE' align=center>" + lineItem.getRequestDate () + "&nbsp;</td>" );
                    buf.append ( "<td  bgcolor='#FFFFEE'  class='NArialL' align=center>" + lineItem.getScheduleDate () + "&nbsp;</td>" );
                    buf.append ( "<td  bgcolor='#FFFFEE'  class='NArialL' align=center>" + lineItem.getRevisedDate () + "&nbsp;</td>" );
                    buf.append ( "<td  class='NArialL' bgcolor='#FFFFEE' align=center>" + lineItem.getIsTaxableAsString () + "&nbsp;</td>" );
                    buf.append ( "<td  class='NArialL' bgcolor='#FFFFEE' align=center>" + lineItem.getUnitPriceAsString () + "&nbsp;</td>" );
                    buf.append ( "<td  class='NArialL' bgcolor='#FFFFEE' align=right>" + lineItem.getAmountAsString() + "&nbsp;</td>" );
                    buf.append ( "</tr>" );
                }
                buf.append ( "<tr>" );
                buf.append ( "<td colspan='1'  bgcolor='#FFFFFF' class='NArialL' nowrap>Sub Total</td>" );
                buf.append ( "<td colspan='1' bgcolor='#FFFFFF' class='NArialL' align='center'>" + subTotalQty + "&nbsp;</td>" );
                buf.append ( "<td colspan='9' >&nbsp;</td>" );
                buf.append ( "<td colspan='1' bgcolor='#FFFFFF' class='NArialL' align='right'>" + subTotalAmt + "&nbsp;</td>" );
                buf.append ( "</tr>" );
            }
        }
        buf.append ( "</table>" );
        buf.append ( "</td></tr>" );

        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );
        buf.append ( "<tr><td colspan=5><img src='http://" + host + "/" + ConfigManager.getChipTracContext () + "/jsp/includes/images/spacer.gif' height=5></td></tR>" );

        buf.append ( "<tr>" );
        buf.append ( "<td>" );
        buf.append ( "<table width='80%' border=1 align=left bordercolor='#000000'  cellspacing='0' cellpadding='0'>" );
        buf.append ( "<tr>" );
        buf.append ( "<td bgcolor='#DEE1E2' class='NArialL'>Banking Information:</td>" );
        buf.append ( "</tr>" );
        buf.append ( "<tr>" );
        buf.append ( "<td valign='top' class='NArialL' bgcolor='#FFFFEE'>" );
        buf.append (( (bankInfo.getBankName() == null || bankInfo.getBankName().equals("")) ? "" : bankInfo.getBankName()) );
        buf.append("<br>");
        buf.append (( (bankInfo.getAddress() == null || bankInfo.getAddress().equals("")) ? "" : bankInfo.getAddress()+ ", ")  + ( (bankInfo.getCity() == null || bankInfo.getCity().equals("")) ? "" : bankInfo.getCity()) );
        buf.append("<br>");
        buf.append (( (bankInfo.getState() == null || bankInfo.getState().equals("")) ? "" : bankInfo.getState()+ " - ")  + ( (bankInfo.getZipCode() == null || bankInfo.getZipCode().equals("")) ? "" : bankInfo.getZipCode()+ ", ")  + ( (bankInfo.getCountry() == null || bankInfo.getCountry().equals("")) ? "" : bankInfo.getCountry()) );
        buf.append("<br>");
        buf.append (( (bankInfo.getAba() == null || bankInfo.getAba().equals("")) ? "" : "ABA :" + bankInfo.getAba()+"&nbsp;&nbsp;"));
        buf.append (( (bankInfo.getAcct() == null || bankInfo.getAcct().equals("")) ? "" : "Acct : "+bankInfo.getAcct()+"&nbsp;&nbsp;"));
        buf.append (( (bankInfo.getSwiftCode() == null || bankInfo.getSwiftCode().equals("")) ? "" : "  SwiftCode : "+bankInfo.getSwiftCode()) );
        buf.append("<br>");
        buf.append ( "</td></tr>" );
        buf.append ( "</table>" );
        buf.append ( "</td>" );

        buf.append ( "<td>" );
        buf.append("&nbsp;");
        buf.append ( "</td>" );
        buf.append ( "<td>" );
        buf.append("&nbsp;");
        buf.append ( "</td>" );
        buf.append ( "<td>" );
        buf.append("&nbsp;");
        buf.append ( "</td>" );

        buf.append ( "<td align='right'>" );
        buf.append ( "<table width='80%' border=1  bordercolor='#000000'  cellspacing='0' cellpadding='0'>" );
        buf.append ( "<tr>" );
        buf.append ( "<td bgcolor='#DEE1E2' class='NArialL'>Total</td><td bgcolor='#DEE1E2' class='NArialL'  align='right'>" + salesOrder.getSubTotalAsString() + "</td>" );
        buf.append ( "</tr>" );
        buf.append ( "<tr><td bgcolor='#DEE1E2' class='NArialL'>Sales Tax</td><td bgcolor='#DEE1E2'  class='NArialL' align='right'>" + salesOrder.getSalesTaxAsString() + "</td>" );
        buf.append ( "</tr>" );
        buf.append ( "<tr><td bgcolor='#DEE1E2' class='NArialL'>Freight</td><td bgcolor='#DEE1E2'  class='NArialL' align='right'>" + salesOrder.getFrieghtAsString() + "</td>" );
        buf.append ( "</tr>" );
        buf.append ( "<tr><td bgcolor='#DEE1E2' class='NArialL'>" + salesOrder.getMiscName () + "</td><td class='NArialL' bgcolor='#DEE1E2' align='right'>" + salesOrder.getMiscAsString() + "</td>" );
        buf.append ( "</tr>    " );
        buf.append ( "<tr><td bgcolor='#DEE1E2' class='NArialL'>Balance Due</td><td  class='NArialL' bgcolor='#DEE1E2' align='right'>" + StringUtils.formatAmount((salesOrder.getSubTotalAsDouble() + salesOrder.getSalesTaxAsDouble() + salesOrder.getFrieghtAsDouble() + salesOrder.getMiscAsDouble()), "$###,###.##") + "</td>" );
        buf.append ( "</tr>    " );
        buf.append ( "</table>" );
        buf.append ( "</td>" );
        buf.append ( "</tr>");

        buf.append ( "</table>");
        buf.append("</div1>");

        buf.append ( "<div style='page-break-after: always;'>&nbsp;</div><table width='100%' cellspacing='5' cellpadding='0' border=0 align=center>" );

        buf.append ( "<TR>" );
        buf.append ( "<TD width='100%' colspan='3' class='viewdata1'>&nbsp;</TD>" );
        buf.append ( "</TR>" );

        buf.append ( "</table>" );
        buf.append ( "</body></html>" );

        return buf.toString ();
    }


    //Added by Suresh on 28 May 2004 to get the PDF file
    public static String getProFormaPDFFile ( String host, String salesOrderId ) throws ScalarException
    {
        String fileXMLPath = null;
        String filePDFPath = null;
        String fileXSLTPath = null;

        SalesOrder salesOrder = null;
        BankInfo bankInfo = null;
        if ( salesOrderId != null )
        {
            salesOrder = SalesOrderDAO.loadSalesOrder ( salesOrderId );
            bankInfo   = ProFormaInvoiceDAO.loadBankInfo(Integer.parseInt(salesOrderId));
        }

        int customerId = SalesOrderDAO.loadCustomerId ( salesOrder.getSalesOrderId () );
        ArrayList presentList = SalesOrderDAO.loadOrderLineItemsByCustomerId ( salesOrder.getSalesOrderId (), customerId );
        int odmId = salesOrder.getOdmId() ;
        //SalesOrderDAO.loadCustomerPartNumbersForLineItems ( null, presentList, customerId, odmId );


        if ( presentList != null )
        {
            Collections.sort ( presentList, new PackingSlipComparator () );
        }


        /*if ( ! (salesOrder.getEndUser ().trim ().equals ( "" ) ) )
        {
            int endUserId = EndUserDAO.getEndUserIdByName ( salesOrder.getEndUser (), salesOrder.getCustomerId () );
            // Commented by veeru on 16th June 2004
            //ApproveOrderAction.loadEndUserContactPersonDetails ( salesOrder, endUserId );

            SalesOrderDAO.loadEndUserPartNumbersForLineItems ( null, presentList, endUserId );
        }*/

        String saAsXML = formatAsXML ( salesOrder, presentList, bankInfo );

        if ( saAsXML == null )
        {
            return fileXMLPath;
        }

        FileWriter fWriter = null;
        File saPDFAttachment = null;
        File saXML = null;

        try
        {
            // CREATE TEMPORARY ATTACHMENT FILE
            String mailingTempDir = ConfigManager.getMailerTempDir ();
            File tempDir = new File ( mailingTempDir ).getCanonicalFile ();
            tempDir.mkdir ();

            String salesNo = salesOrder.getSalesOrderNo ();
            String xmlFileName = "Pro_Forma_Invoice" + salesNo + ".xml";
            String saAttachmentPDFFileName = "Pro_Forma_Invoice" + salesNo + ".pdf";

            String xsltFileName = ConfigManager.getProFormaInvoiceXml2PdfXslFile ();

            saXML = new File ( tempDir.getCanonicalPath (), xmlFileName );
            saXML.deleteOnExit ();

            saPDFAttachment = new File ( tempDir.getCanonicalPath (), saAttachmentPDFFileName );
            saPDFAttachment.deleteOnExit ();

            if ( ( saXML.exists () == true ) || ( saXML.createNewFile () == true ) )
            {
                fWriter = new FileWriter ( saXML, false );
                fWriter.write ( saAsXML );
                fWriter.close ();
                fWriter = null;

                fileXMLPath = saXML.getCanonicalPath ().toLowerCase ();
                filePDFPath = saPDFAttachment.getCanonicalPath ().toLowerCase ();

                boolean success = PDFGenerator.convertXML2PDF ( fileXMLPath, xsltFileName, filePDFPath );
            }
        }
        catch ( Exception e )
        {
            System.out.println ( "Exception while creating Pro Forma Invoice PDF file" );
            e.printStackTrace ();
        }
        finally
        {
            if ( fWriter != null )
            {
                try
                {
                    fWriter.close ();
                    fWriter = null;
                }
                catch ( IOException ignore )
                {
                }
            }
        }

        return filePDFPath;
    }

    // Added by suresh on May 28th 2004. Generates the XML for Pro Forma Invoice
    public static String formatAsXML ( SalesOrder salesOrder, ArrayList presentList, BankInfo bankInfo ) throws ScalarException
    {
        StringBuffer buf = new StringBuffer ( 2098 );
		salesOrder.setChangeNumber(SalesOrderDAO.loadChangeNo ( salesOrder.getSalesOrderId () )  - 1);

        buf.append ( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n" );
        buf.append ( "<proFormaInvoice>" + "\n" );
        buf.append ( "<logo>" + ConfigManager.getChipTracImagesDir () + ConfigManager.getScalarLogo () + "</logo>" + "\n" );
        buf.append ( "<selfAddress>" + "\n" );
        //To get client Address
        buf.append ( "<name><![CDATA[" + salesOrder.getClientName () + "]]></name>" + "\n" );
        Address clientAddress = salesOrder.getClientAddressAsObject ();

        buf.append ( "<address1><![CDATA[" + clientAddress.getAddress1 () + "]]></address1>" + "\n" );
        buf.append ( "<address2><![CDATA[" + clientAddress.getAddress2 () + "]]></address2>" + "\n" );
        buf.append ( "<address3><![CDATA[" + clientAddress.getAddress3 () + "]]></address3>" + "\n" );
        buf.append ( "<address4><![CDATA[" + clientAddress.getAddress4 () + "]]></address4>" + "\n" );
        StringBuffer cityStateZip = new StringBuffer ( "" );

        if ( !clientAddress.getCity ().equals ( "" ) ) cityStateZip.append ( clientAddress.getCity () + ", " );
        if ( !clientAddress.getState ().equals ( "" ) ) cityStateZip.append ( clientAddress.getState () + " - " );
        if ( !clientAddress.getZipCode ().equals ( "" ) ) cityStateZip.append ( clientAddress.getZipCode () + ", " );
        cityStateZip.append ( clientAddress.getCountry () );

        buf.append ( "<cityStateZip><![CDATA[" + cityStateZip + "]]></cityStateZip>" + "\n" );

        StringBuffer phFax = new StringBuffer ();
        if ( !clientAddress.getPhoneNumber ().equals ( "" ) ) phFax.append ( "Ph." + clientAddress.getPhoneNumber () + ", " );
        if ( !clientAddress.getFaxNumber ().equals ( "" ) ) phFax.append ( "Fax." + clientAddress.getFaxNumber () );

        buf.append ( "<phoneFax><![CDATA[" + phFax + "]]></phoneFax>" + "\n" );
        buf.append ( "</selfAddress>" + "\n" );

        Address address = salesOrder.getBillingAddressAsObject ();

        String customerName = salesOrder.getCustomerName ();
        if ( salesOrder.getCustomerName ().equals ( salesOrder.getContactPerson () ) )
        {
            customerName = "";
        }

        buf.append ( "<billToAddress>" + "\n" );

        if( salesOrder.getBillingAddressAsObject().getContactPerson() != null && salesOrder.getCustomerName().trim().length() !=0 )
        {
            if( ! salesOrder.getBillingAddressAsObject().getContactPerson().equals( salesOrder.getCustomerName() ) )
            {
                buf.append ( "<name><![CDATA[" + customerName + "]]></name>" + "\n" );
            }
        }
        buf.append ( "<contactPerson><![CDATA[" + address.getContactPerson () + "]]></contactPerson>" + "\n" );
        buf.append ( "<address1><![CDATA[" + address.getAddress1 () + "]]></address1>" + "\n" );
        buf.append ( "<address2><![CDATA[" + address.getAddress2 () + "]]></address2>" + "\n" );
        buf.append ( "<address3><![CDATA[" + address.getAddress3 () + "]]></address3>" + "\n" );
        buf.append ( "<address4><![CDATA[" + address.getAddress4 () + "]]></address4>" + "\n" );

        buf.append ( "<city><![CDATA["+ address.getCity () + "]]></city>" + "\n" );
        buf.append ( "<stateZipCountry><![CDATA[" );
        if(address.getState ()!=null && !(address.getState ().equals("")))
        {
            buf.append(address.getState ());
        }
        if(address.getZipCode()!=null && !(address.getZipCode().equals("")))
        {
            if(address.getState ()!=null && !(address.getState ().equals("")))
            {
                buf.append(" - ");
            }
            buf.append(address.getZipCode());
        }
        if(address.getCountry ()!=null && !(address.getCountry ().equals("")))
        {
            if((address.getZipCode()!=null && !(address.getZipCode().equals("")))||(address.getState ()!=null && !(address.getState ().equals(""))))
            {
                buf.append(", ");
            }
            buf.append(address.getCountry ());
        }
        buf.append ( "]]></stateZipCountry>" + "\n" );


        /*buf.append ( "<phone><![CDATA[" + ( address.getPhoneNumber () == null ? "" : address.getPhoneNumber () ) + "]]></phone>" + "\n" );
        buf.append ( "<cell><![CDATA[" + ( address.getCellNumber () == null ? "" : address.getCellNumber () ) + "]]></cell>" + "\n" );
        buf.append ( "<fax><![CDATA[" + ( address.getFaxNumber () == null ? "" : address.getFaxNumber () ) + "]]></fax>" + "\n" );
        buf.append ( "<email><![CDATA[" + ( address.getEmail () == null ? "" : address.getEmail () ) + "]]></email>" + "\n" ); */
        //modified by varma(06 jul 2004)
         buf.append ( "<phone><![CDATA[" + ( ( ( address.getPhoneNumber () != null ) && ( address.getPhoneNumber() .trim().length() > 0) )? "Tel:"+address.getPhoneNumber () : "" ) + "]]></phone>" + "\n" );
        buf.append ( "<cell><![CDATA[" + ( ( ( address.getCellNumber () != null ) && ( address.getCellNumber() .trim() .length() > 0 ) )? "Cell No:"+ address.getCellNumber () : "") + "]]></cell>" + "\n" );
        buf.append ( "<fax><![CDATA[" + ( ( ( address.getFaxNumber () != null ) && (address.getFaxNumber() .trim() .length() > 0 ) ) ? "Fax:"+ address.getFaxNumber () : "" ) + "]]></fax>" + "\n" );
        buf.append ( "<email><![CDATA[" + ( ( ( address.getEmail () != null ) && (address.getEmail() .trim().length() > 0 ) ) ? "Email:"+ address.getEmail () : "") + "]]></email>" + "\n" );
        buf.append ( "</billToAddress>" + "\n" );

        address = salesOrder.getShippingAddressAsObject ();

        buf.append ( "<shipToAddress>" + "\n" );

        //buf.append ( "<name><![CDATA[" + salesOrder.getCustomerName () + "]]></name>" + "\n" );
        String shipersName = salesOrder.getOdm() != null && salesOrder.getOdm().length() > 0 ? salesOrder.getOdm() : salesOrder.getCustomerName () ;
        buf.append ( "<name><![CDATA[" + shipersName + "]]></name>" + "\n" );

        buf.append ( "<contactPerson><![CDATA[" + address.getContactPerson () + "]]></contactPerson>" + "\n" );
        buf.append ( "<address1><![CDATA[" + address.getAddress1 () + "]]></address1>" + "\n" );
        buf.append ( "<address2><![CDATA[" + address.getAddress2 () + "]]></address2>" + "\n" );
        buf.append ( "<address3><![CDATA[" + address.getAddress3 () + "]]></address3>" + "\n" );
        buf.append ( "<address4><![CDATA[" + address.getAddress4 () + "]]></address4>" + "\n" );

        buf.append ( "<city><![CDATA["+ address.getCity () + "]]></city>" + "\n" );
        buf.append ( "<stateZipCountry><![CDATA[" );
        if(address.getState ()!=null && !(address.getState ().equals("")))
        {
            buf.append(address.getState ());
        }
        if(address.getZipCode()!=null && !(address.getZipCode().equals("")))
        {
            if(address.getState ()!=null && !(address.getState ().equals("")))
            {
                buf.append(" - ");
            }
            buf.append(address.getZipCode());
        }
        if(address.getCountry ()!=null && !(address.getCountry ().equals("")))
        {
            if((address.getZipCode()!=null && !(address.getZipCode().equals("")))||(address.getState ()!=null && !(address.getState ().equals(""))))
            {
                buf.append(", ");
            }
            buf.append(address.getCountry ());
        }
        buf.append ( "]]></stateZipCountry>" + "\n" );

        /*buf.append ( "<phone><![CDATA[" + ( address.getPhoneNumber () == null ? "" : address.getPhoneNumber () ) + "]]></phone>" + "\n" );
        buf.append ( "<cell><![CDATA[" + ( address.getCellNumber () == null ? "" : address.getCellNumber () ) + "]]></cell>" + "\n" );
        buf.append ( "<fax><![CDATA[" + ( address.getFaxNumber () == null ? "" : address.getFaxNumber () ) + "]]></fax>" + "\n" );
        buf.append ( "<email><![CDATA[" + ( address.getEmail () == null ? "" : address.getEmail () ) + "]]></email>" + "\n" );*/
        //modified by varma 06 jul 2004
         buf.append ( "<phone><![CDATA[" + ( ( ( address.getPhoneNumber () != null ) && ( address.getPhoneNumber() .trim().length() > 0) )? "Tel:"+address.getPhoneNumber () : "" ) + "]]></phone>" + "\n" );
        buf.append ( "<cell><![CDATA[" + ( ( ( address.getCellNumber () != null ) && ( address.getCellNumber() .trim() .length() > 0 ) )? "Cell No:"+ address.getCellNumber () : "") + "]]></cell>" + "\n" );
        buf.append ( "<fax><![CDATA[" + ( ( ( address.getFaxNumber () != null ) && (address.getFaxNumber() .trim() .length() > 0 ) ) ? "Fax:"+ address.getFaxNumber () : "" ) + "]]></fax>" + "\n" );
        buf.append ( "<email><![CDATA[" + ( ( ( address.getEmail () != null ) && (address.getEmail() .trim().length() > 0 ) ) ? "Email:"+ address.getEmail () : "") + "]]></email>" + "\n" );
        buf.append ( "</shipToAddress>" + "\n" );

        buf.append ( "<information>" + "\n" );
        buf.append ( "<customerPO><![CDATA[" + salesOrder.getCustomerPO () + "]]></customerPO>" + "\n" );
        buf.append ( "<salesOrder><![CDATA[" + salesOrder.getSalesOrderNo () + "]]></salesOrder>" + "\n" );
        buf.append ( "<orderDate><![CDATA[" + salesOrder.getBookingdateAsString () + "]]></orderDate>" + "\n" );
        buf.append ( "<shipVia><![CDATA[" + salesOrder.getShippingMethod () + "]]></shipVia>" + "\n" );
        buf.append ( "<salesPerson><![CDATA[" + salesOrder.getSalesPerson () + "]]></salesPerson>" + "\n" );
        buf.append ( "<regionalRep><![CDATA[" + salesOrder.getRegionalRep () + "]]></regionalRep>" + "\n" );
        buf.append ( "<delTerms><![CDATA[" + salesOrder.getDeliveryTerms () + "]]></delTerms>" + "\n" );
        buf.append ( "<payTerms><![CDATA[" + ( salesOrder.getShippingTerms ().trim ().equals ( "-1" ) ? "" : salesOrder.getShippingTerms () ) + "]]></payTerms>" + "\n" );
        buf.append ( "</information>" + "\n" );

        LineItem lineItem = null;

        ArrayList presentListWithSubtotals = loadLineItemsWithSubTotals ( presentList );

        buf.append ( "<lineItems>" + "\n" );

        String mfgPartNumberLabel = MessageResources.getMessageResources ( Labels.APPLICATION_RESOURCE_PROPERTIES ).getMessage ( "label.mfgPartNumber" );
        if ( mfgPartNumberLabel == null )
        {
            mfgPartNumberLabel = Labels.DEFAULT_MFG_PART_NUMBER_LABEL;
        }

        String customerPartNumberLabel = MessageResources.getMessageResources ( Labels.APPLICATION_RESOURCE_PROPERTIES ).getMessage ( "label.customerPartNumber" );
        if ( customerPartNumberLabel == null )
        {
            customerPartNumberLabel = Labels.DEFAULT_CUSTOMER_PART_NUMBER_LABEL;
        }

        buf.append ( "<labelMfgPartNumber><![CDATA[" + mfgPartNumberLabel + "]]></labelMfgPartNumber>" );
        buf.append ( "<labelCustPartNumber><![CDATA[" + customerPartNumberLabel + "]]></labelCustPartNumber>" );

        for ( int i = 0; i < presentListWithSubtotals.size (); i++ )
        {
            HashMap hashMap = ( HashMap ) presentListWithSubtotals.get ( i );
            Iterator iterator = hashMap.keySet ().iterator ();
            while ( iterator.hasNext () )
            {
                ArrayList list = ( ArrayList ) iterator.next ();

                SubTotal subTotal = ( SubTotal ) hashMap.get ( list );
                String subTotalQty = subTotal.getSubTotalQty ();
                String subTotalAmt = subTotal.getSubTotalAmt ();

                int size = list.size ();
                buf.append ( "<group>" + "\n" );

                for ( int j = 0; j < size; j++ )
                {
                    lineItem = ( LineItem ) list.get ( j );
                    buf.append ( "<lineItem>" + "\n" );
                    buf.append ( "<poLineItem><![CDATA[" + lineItem.getPoLineItemNo () + "]]></poLineItem>" + "\n" );
                    buf.append ( "<reqQty><![CDATA[" + lineItem.getQuantity () + "]]></reqQty>" + "\n" );
                    buf.append ( "<um><![CDATA[" + "ea" + "]]></um>" + "\n" );
                    buf.append ( "<mfgPartNumber><![CDATA[" + lineItem.getManufacturingPartNo () + "]]></mfgPartNumber>" + "\n" );
                    buf.append ( "<customerPartNumber><![CDATA[" + lineItem.getCustomerPartNo () + "]]></customerPartNumber>" + "\n" );
                    buf.append ( "<description><![CDATA[" + lineItem.getDescription () + "]]></description>" + "\n" );
                    buf.append ( "<requestDate><![CDATA[" + lineItem.getRequestDate () + "]]></requestDate>" + "\n" );
                    buf.append ( "<scheduleDate><![CDATA[" + lineItem.getScheduleDate () + "]]></scheduleDate>" + "\n" );
                    buf.append ( "<revisedShipDate><![CDATA[" + lineItem.getRevisedDate () + "]]></revisedShipDate>" + "\n" );
                    buf.append ( "<taxable><![CDATA[" + lineItem.getIsTaxableAsString () + "]]></taxable>" + "\n" );
                    buf.append ( "<unitPrice><![CDATA[" + lineItem.getUnitPriceAsString () + "]]></unitPrice>" + "\n" );
                    buf.append ( "<extendedPrice><![CDATA[" + lineItem.getExtendedPriceAsString () + "]]></extendedPrice>" + "\n" );
                    buf.append ( "</lineItem>" + "\n" );
                }
                buf.append ( "<subTotalQty><![CDATA[" + subTotalQty + "]]></subTotalQty>" + "\n" );
                buf.append ( "<subTotalAmt><![CDATA[" + subTotalAmt + "]]></subTotalAmt>" + "\n" );
                buf.append ( "</group>" + "\n" );
            }
        }
        buf.append ( "</lineItems>" + "\n" );

        buf.append ( "<bankInformation>" );
        buf.append ( "<bankName><![CDATA[" + ( (bankInfo.getBankName() == null || bankInfo.getBankName().equals("")) ? "" : bankInfo.getBankName()) + "]]></bankName>" + "\n" );
        buf.append ( "<address><![CDATA[" + ( (bankInfo.getAddress() == null || bankInfo.getAddress().equals("")) ? "" : bankInfo.getAddress()+ ", ")  + ( (bankInfo.getCity() == null || bankInfo.getCity().equals("")) ? "" : bankInfo.getCity()) + "]]></address>" + "\n" );
        buf.append ( "<state><![CDATA[" + ( (bankInfo.getState() == null || bankInfo.getState().equals("")) ? "" : bankInfo.getState()+ " - ")  + ( (bankInfo.getZipCode() == null || bankInfo.getZipCode().equals("")) ? "" : bankInfo.getZipCode()+ ", ")  + ( (bankInfo.getCountry() == null || bankInfo.getCountry().equals("")) ? "" : bankInfo.getCountry()) + "]]></state>" + "\n" );
        buf.append ( "<account><![CDATA[" + ( (bankInfo.getAba() == null || bankInfo.getAba().equals("")) ? "" : "ABA :" + bankInfo.getAba()) + ( (bankInfo.getAcct() == null || bankInfo.getAcct().equals("")) ? "" : "  Acct : "+bankInfo.getAcct())  +  ( (bankInfo.getSwiftCode() == null || bankInfo.getSwiftCode().equals("")) ? "" : "  SwiftCode : "+bankInfo.getSwiftCode()) + "]]></account>" + "\n" );
        buf.append ( "</bankInformation>" + "\n" );

        buf.append ( "<total><![CDATA[" + salesOrder.getFinalSubTotalAsString () + "]]></total>" + "\n" );
        buf.append ( "<salesTax><![CDATA[" + salesOrder.getSalesTaxAsString () + "]]></salesTax>" + "\n" );
        buf.append ( "<freight><![CDATA[" + salesOrder.getFrieghtAsString () + "]]></freight>" + "\n" );
        buf.append ( "<misc name=\"" + salesOrder.getMiscName () + "\"><![CDATA[" + salesOrder.getMiscAsString () + "]]></misc>" + "\n" );
        buf.append ( "<balanceDue><![CDATA[" + salesOrder.getFinalOrderTotalAsString () + "]]></balanceDue>" + "\n" );

        buf.append ( "</proFormaInvoice>" + "\n" );

        return buf.toString ();
    }


    // Separates the line items based on Manufacturing Part Nos and calculates SubTotals.
    public static ArrayList loadLineItemsWithSubTotals ( ArrayList lineItemList )
    {
        ArrayList list = new ArrayList ();
        LinkedHashMap hash = new LinkedHashMap ();
        for ( int i = 0; i < lineItemList.size (); i++ )
        {
            LineItem lineItem = ( LineItem ) lineItemList.get ( i );
            String mfgPartNumber = lineItem.getManufacturingPartNo ();
            if ( !( hash.containsKey ( mfgPartNumber ) ) )
            {
                hash.put ( mfgPartNumber, new ArrayList () );
            }
            ArrayList arrList = ( ArrayList ) hash.get ( mfgPartNumber );
            arrList.add ( lineItem );
        }


        Iterator iterator = hash.keySet ().iterator ();
        LinkedHashMap hashMap = new LinkedHashMap ();

        while ( iterator.hasNext () )
        {
            String str = ( String ) iterator.next ();
            ArrayList arrList = ( ArrayList ) hash.get ( str );
            SubTotal subTotal = new SubTotal();

            double subTotalAmt = 0.0;
            int subTotalQty = 0;
            for ( int i = 0; i < arrList.size (); i++ )
            {
                subTotalAmt = subTotalAmt + ( ( LineItem ) arrList.get ( i ) ).getExtendedPriceAsDouble();
                subTotalQty = subTotalQty + ( ( LineItem ) arrList.get ( i ) ).getToBeShippedQty();
            }
            subTotal.setSubTotalQty ( Integer.toString ( subTotalQty ) );
            subTotal.setSubTotalAmt ( StringUtils.formatAmount ( subTotalAmt, "$###,###.##" ) );
            hashMap.put ( arrList, subTotal );
        }
        list.add ( hashMap );

        return list;
    }


    public static String coolstatus = null;
}